package handlers

import (
	"gin-chat-server/common"
	"gin-chat-server/dto"
	service "gin-chat-server/services"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
)

type ChatHandler struct {
	chatService *service.ChatService
}

func NewChatHandler() *ChatHandler {
	return &ChatHandler{
		chatService: service.NewChatService(),
	}
}

// 聊天室相关接口

// 创建聊天室
func (h *ChatHandler) CreateRoom(c *gin.Context) {
	var req dto.CreateRoomRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		common.ResponseError(c, http.StatusBadRequest, "Invalid request body")
		return
	}

	userID := common.GetCurrentUserID(c)
	if userID == "" {
		common.ResponseError(c, http.StatusUnauthorized, "User not authenticated")
		return
	}

	room, err := h.chatService.CreateRoom(&req, userID)
	if err != nil {
		common.ResponseError(c, http.StatusInternalServerError, "Failed to create room: "+err.Error())
		return
	}

	common.ResponseSuccess(c, gin.H{
		"id":          room.ID,
		"name":        room.Name,
		"description": room.Description,
		"type":        room.Type,
		"creator_id":  room.CreatorID,
		"created_at":  room.CreatedAt,
	})
}

// 获取用户聊天室列表
func (h *ChatHandler) GetUserRooms(c *gin.Context) {
	userID := common.GetCurrentUserID(c)
	if userID == "" {
		common.ResponseError(c, http.StatusUnauthorized, "User not authenticated")
		return
	}

	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))

	rooms, total, err := h.chatService.GetUserRooms(userID, page, pageSize)
	if err != nil {
		common.ResponseError(c, http.StatusInternalServerError, "Failed to get rooms: "+err.Error())
		return
	}

	common.ResponseSuccess(c, gin.H{
		"data":        rooms,
		"total":       total,
		"page":        page,
		"page_size":   pageSize,
		"total_pages": (total + int64(pageSize) - 1) / int64(pageSize),
	})
}

// 获取聊天室详情
func (h *ChatHandler) GetRoomByID(c *gin.Context) {
	roomID := c.Param("room_id")
	userID := common.GetCurrentUserID(c)
	if userID == "" {
		common.ResponseError(c, http.StatusUnauthorized, "User not authenticated")
		return
	}

	room, err := h.chatService.GetRoomByID(roomID, userID)
	if err != nil {
		common.ResponseError(c, http.StatusNotFound, "Room not found: "+err.Error())
		return
	}

	common.ResponseSuccess(c, room)
}

// 加入聊天室
func (h *ChatHandler) JoinRoom(c *gin.Context) {
	roomID := c.Param("room_id")
	userID := common.GetCurrentUserID(c)
	if userID == "" {
		common.ResponseError(c, http.StatusUnauthorized, "User not authenticated")
		return
	}

	err := h.chatService.JoinRoom(roomID, userID)
	if err != nil {
		common.ResponseError(c, http.StatusBadRequest, "Failed to join room: "+err.Error())
		return
	}

	common.ResponseSuccess(c, gin.H{"message": "Successfully joined room"})
}

// 离开聊天室
func (h *ChatHandler) LeaveRoom(c *gin.Context) {
	roomID := c.Param("room_id")
	userID := common.GetCurrentUserID(c)
	if userID == "" {
		common.ResponseError(c, http.StatusUnauthorized, "User not authenticated")
		return
	}

	err := h.chatService.LeaveRoom(roomID, userID)
	if err != nil {
		common.ResponseError(c, http.StatusBadRequest, "Failed to leave room: "+err.Error())
		return
	}

	common.ResponseSuccess(c, gin.H{"message": "Successfully left room"})
}

// 消息相关接口

// 发送消息
func (h *ChatHandler) SendMessage(c *gin.Context) {
	roomID := c.Param("room_id")
	userID := common.GetCurrentUserID(c)
	if userID == "" {
		common.ResponseError(c, http.StatusUnauthorized, "User not authenticated")
		return
	}

	var req dto.SendMessageRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		common.ResponseError(c, http.StatusBadRequest, "Invalid request body")
		return
	}

	message, err := h.chatService.SendMessage(roomID, userID, &req)
	if err != nil {
		common.ResponseError(c, http.StatusInternalServerError, "Failed to send message: "+err.Error())
		return
	}

	common.ResponseSuccess(c, gin.H{
		"id":         message.ID,
		"room_id":    message.RoomID,
		"user_id":    message.UserID,
		"content":    message.Content,
		"type":       message.Type,
		"status":     message.Status,
		"reply_to":   message.ReplyTo,
		"file_url":   message.FileURL,
		"file_name":  message.FileName,
		"file_size":  message.FileSize,
		"created_at": message.CreatedAt,
	})
}

// 获取聊天室消息列表
func (h *ChatHandler) GetRoomMessages(c *gin.Context) {
	roomID := c.Param("room_id")
	userID := common.GetCurrentUserID(c)
	if userID == "" {
		common.ResponseError(c, http.StatusUnauthorized, "User not authenticated")
		return
	}

	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
	before := c.Query("before")

	messages, total, err := h.chatService.GetRoomMessages(roomID, userID, page, pageSize, before)
	if err != nil {
		common.ResponseError(c, http.StatusInternalServerError, "Failed to get messages: "+err.Error())
		return
	}

	common.ResponseSuccess(c, gin.H{
		"data":        messages,
		"total":       total,
		"page":        page,
		"page_size":   pageSize,
		"total_pages": (total + int64(pageSize) - 1) / int64(pageSize),
	})
}

// 标记消息为已读
func (h *ChatHandler) MarkMessageAsRead(c *gin.Context) {
	messageID := c.Param("message_id")
	userID := common.GetCurrentUserID(c)
	if userID == "" {
		common.ResponseError(c, http.StatusUnauthorized, "User not authenticated")
		return
	}

	err := h.chatService.MarkMessageAsRead(messageID, userID)
	if err != nil {
		common.ResponseError(c, http.StatusInternalServerError, "Failed to mark message as read: "+err.Error())
		return
	}

	common.ResponseSuccess(c, gin.H{"message": "Message marked as read"})
}

// 标记房间所有消息为已读
func (h *ChatHandler) MarkRoomAsRead(c *gin.Context) {
	roomID := c.Param("room_id")
	userID := common.GetCurrentUserID(c)
	if userID == "" {
		common.ResponseError(c, http.StatusUnauthorized, "User not authenticated")
		return
	}

	// 获取房间所有未读消息并标记为已读
	page := 1
	pageSize := 1000 // 一次处理大量消息

	for {
		messages, total, err := h.chatService.GetRoomMessages(roomID, userID, page, pageSize, "")
		if err != nil {
			common.ResponseError(c, http.StatusInternalServerError, "Failed to get messages: "+err.Error())
			return
		}

		if len(messages) == 0 {
			break
		}

		for _, msg := range messages {
			if !msg.IsRead {
				h.chatService.MarkMessageAsRead(msg.ID, userID)
			}
		}

		if int64(page*pageSize) >= total {
			break
		}
		page++
	}

	common.ResponseSuccess(c, gin.H{"message": "All messages marked as read"})
}

// 好友相关接口

// 发送好友请求
func (h *ChatHandler) SendFriendRequest(c *gin.Context) {
	userID := common.GetCurrentUserID(c)
	if userID == "" {
		common.ResponseError(c, http.StatusUnauthorized, "User not authenticated")
		return
	}

	var req dto.SendFriendRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		common.ResponseError(c, http.StatusBadRequest, "Invalid request body")
		return
	}

	request, err := h.chatService.SendFriendRequest(userID, req.ReceiverID, req.Message)
	if err != nil {
		common.ResponseError(c, http.StatusBadRequest, "Failed to send friend request: "+err.Error())
		return
	}

	common.ResponseSuccess(c, gin.H{
		"id":          request.ID,
		"sender_id":   request.SenderID,
		"receiver_id": request.ReceiverID,
		"status":      request.Status,
		"message":     request.Message,
		"created_at":  request.CreatedAt,
	})
}

// 响应好友请求
func (h *ChatHandler) RespondFriendRequest(c *gin.Context) {
	userID := common.GetCurrentUserID(c)
	if userID == "" {
		common.ResponseError(c, http.StatusUnauthorized, "User not authenticated")
		return
	}

	var req dto.RespondFriendRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		common.ResponseError(c, http.StatusBadRequest, "Invalid request body")
		return
	}

	err := h.chatService.RespondFriendRequest(req.RequestID, userID, req.Status)
	if err != nil {
		common.ResponseError(c, http.StatusBadRequest, "Failed to respond to friend request: "+err.Error())
		return
	}

	common.ResponseSuccess(c, gin.H{"message": "Friend request processed successfully"})
}

// 获取好友列表
func (h *ChatHandler) GetFriends(c *gin.Context) {
	userID := common.GetCurrentUserID(c)
	if userID == "" {
		common.ResponseError(c, http.StatusUnauthorized, "User not authenticated")
		return
	}

	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))

	friends, total, err := h.chatService.GetFriends(userID, page, pageSize)
	if err != nil {
		common.ResponseError(c, http.StatusInternalServerError, "Failed to get friends: "+err.Error())
		return
	}

	common.ResponseSuccess(c, gin.H{
		"data":        friends,
		"total":       total,
		"page":        page,
		"page_size":   pageSize,
		"total_pages": (total + int64(pageSize) - 1) / int64(pageSize),
	})
}

// 获取好友请求列表
func (h *ChatHandler) GetFriendRequests(c *gin.Context) {
	userID := common.GetCurrentUserID(c)
	if userID == "" {
		common.ResponseError(c, http.StatusUnauthorized, "User not authenticated")
		return
	}

	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))

	requests, total, err := h.chatService.GetFriendRequests(userID, page, pageSize)
	if err != nil {
		common.ResponseError(c, http.StatusInternalServerError, "Failed to get friend requests: "+err.Error())
		return
	}

	common.ResponseSuccess(c, gin.H{
		"data":        requests,
		"total":       total,
		"page":        page,
		"page_size":   pageSize,
		"total_pages": (total + int64(pageSize) - 1) / int64(pageSize),
	})
}

// 获取未读消息数量
func (h *ChatHandler) GetUnreadCount(c *gin.Context) {
	userID := common.GetCurrentUserID(c)
	if userID == "" {
		common.ResponseError(c, http.StatusUnauthorized, "User not authenticated")
		return
	}

	// 获取用户所在的所有房间
	rooms, _, err := h.chatService.GetUserRooms(userID, 1, 1000)
	if err != nil {
		common.ResponseError(c, http.StatusInternalServerError, "Failed to get rooms: "+err.Error())
		return
	}

	var totalUnread int64 = 0
	for _, room := range rooms {
		totalUnread += room.UnreadCount
	}

	common.ResponseSuccess(c, gin.H{"unread_count": totalUnread})
}

// 搜索用户
func (h *ChatHandler) SearchUsers(c *gin.Context) {
	query := c.Query("query")
	if query == "" {
		common.ResponseError(c, http.StatusBadRequest, "Query parameter is required")
		return
	}

	userID := common.GetCurrentUserID(c)
	if userID == "" {
		common.ResponseError(c, http.StatusUnauthorized, "User not authenticated")
		return
	}

	// 这里需要实现用户搜索逻辑
	// 暂时返回空结果
	common.ResponseSuccess(c, gin.H{
		"data":        []interface{}{},
		"total":       0,
		"page":        1,
		"page_size":   20,
		"total_pages": 0,
	})
}

// 获取最近联系人
func (h *ChatHandler) GetRecentContacts(c *gin.Context) {
	userID := common.GetCurrentUserID(c)
	if userID == "" {
		common.ResponseError(c, http.StatusUnauthorized, "User not authenticated")
		return
	}

	limit := 10
	if l := c.Query("limit"); l != "" {
		if parsed, err := strconv.Atoi(l); err == nil && parsed > 0 && parsed <= 100 {
			limit = parsed
		}
	}

	// 获取最近的消息房间
	rooms, _, err := h.chatService.GetUserRooms(userID, 1, limit)
	if err != nil {
		common.ResponseError(c, http.StatusInternalServerError, "Failed to get recent contacts: "+err.Error())
		return
	}

	common.ResponseSuccess(c, gin.H{
		"data":  rooms,
		"total": int64(len(rooms)),
		"limit": limit,
	})
}

// 获取聊天统计信息
func (h *ChatHandler) GetChatStats(c *gin.Context) {
	userID := common.GetCurrentUserID(c)
	if userID == "" {
		common.ResponseError(c, http.StatusUnauthorized, "User not authenticated")
		return
	}

	// 获取用户统计信息
	rooms, totalRooms, _ := h.chatService.GetUserRooms(userID, 1, 1000)
	_, totalFriends, _ := h.chatService.GetFriends(userID, 1, 1000)

	// 计算未读消息总数
	var totalUnread int64 = 0
	for _, room := range rooms {
		totalUnread += room.UnreadCount
	}

	stats := &dto.ChatStatsResponse{
		TotalRooms:     totalRooms,
		TotalFriends:   totalFriends,
		UnreadMessages: totalUnread,
	}

	common.ResponseSuccess(c, stats)
}
